/**
 * 错误处理器
 * 提供统一的错误处理、日志记录、用户通知等功能
 */
class ErrorHandler {
    constructor(options = {}) {
        this.debug = options.debug || false;
        this.logger = options.logger || console;
        this.notificationManager = options.notificationManager || null;
        this.errorReporting = options.errorReporting || null;
        this.enableLogging = options.enableLogging !== false;
        this.enableNotifications = options.enableNotifications !== false;
        this.enableReporting = options.enableReporting !== false;

        // 错误类型映射
        this.errorTypes = {
            'NETWORK_ERROR': '网络错误',
            'AUTH_ERROR': '认证错误',
            'PERMISSION_ERROR': '权限错误',
            'VALIDATION_ERROR': '验证错误',
            'SERVER_ERROR': '服务器错误',
            'TIMEOUT_ERROR': '请求超时',
            'PARSE_ERROR': '数据解析错误',
            'UNKNOWN_ERROR': '未知错误'
        };

        // 错误级别映射
        this.errorLevels = {
            'debug': 0,
            'info': 1,
            'warn': 2,
            'error': 3,
            'critical': 4
        };

        // 初始化
        this.init();
    }

    /**
     * 初始化
     */
    init() {
        // 设置全局错误处理
        if (typeof window !== 'undefined') {
            window.addEventListener('error', (event) => {
                this.handleGlobalError(event);
            });

            window.addEventListener('unhandledrejection', (event) => {
                this.handleUnhandledRejection(event);
            });
        }

        // 设置通知回调
        if (this.notificationManager) {
            this.notificationManager.setHandler(this.handleNotification.bind(this));
        }
    }

    /**
     * 处理全局错误
     */
    handleGlobalError(event) {
        const error = {
            message: event.message,
            filename: event.filename,
            lineno: event.lineno,
            colno: event.colno,
            error: event.error,
            type: 'GLOBAL_ERROR',
            level: 'error'
        };

        this.handle(error);
    }

    /**
     * 处理未捕获的Promise
     */
    handleUnhandledRejection(event) {
        const error = {
            message: event.reason?.message || '未处理的Promise拒绝',
            reason: event.reason,
            type: 'UNHANDLED_REJECTION',
            level: 'error'
        };

        this.handle(error);
        event.preventDefault();
    }

    /**
     * 主错误处理方法
     */
    async handle(error, options = {}) {
        const {
            type = 'UNKNOWN_ERROR',
            level = 'error',
            userMessage = null,
            details = null,
            showToast = true,
            report = true
        } = options;

        // 标准化错误对象
        const normalizedError = this.normalizeError(error, type, level);

        // 添加额外信息
        if (details) {
            normalizedError.details = details;
        }

        if (userMessage) {
            normalizedError.userMessage = userMessage;
        }

        // 日志记录
        if (this.enableLogging) {
            await this.logError(normalizedError);
        }

        // 用户通知
        if (this.enableNotifications && showToast) {
            await this.notifyUser(normalizedError);
        }

        // 错误上报
        if (this.enableReporting && report) {
            await this.reportError(normalizedError);
        }

        // 调试模式
        if (this.debug) {
            console.error('[ErrorHandler]', normalizedError);
        }

        return normalizedError;
    }

    /**
     * 标准化错误对象
     */
    normalizeError(error, type, level) {
        const timestamp = new Date().toISOString();
        const id = this.generateErrorId();

        let normalizedError = {
            id,
            timestamp,
            type: type || this.getErrorType(error),
            level: level || this.getErrorLevel(error),
            message: error.message || error.toString() || '未知错误',
            stack: error.stack || null,
            code: error.code || null,
            status: error.status || null,
            url: window?.location?.href || null,
            userAgent: window?.navigator?.userAgent || null
        };

        // 如果是网络错误
        if (error instanceof TypeError && error.message.includes('Network')) {
            normalizedError.type = 'NETWORK_ERROR';
        }

        // 如果是API错误
        if (error.response) {
            normalizedError.response = {
                status: error.response.status,
                statusText: error.response.statusText,
                data: error.response.data
            };

            // 根据状态码设置错误类型
            if (error.response.status === 401) {
                normalizedError.type = 'AUTH_ERROR';
            } else if (error.response.status === 403) {
                normalizedError.type = 'PERMISSION_ERROR';
            } else if (error.response.status === 422) {
                normalizedError.type = 'VALIDATION_ERROR';
            } else if (error.response.status >= 500) {
                normalizedError.type = 'SERVER_ERROR';
            }
        }

        return normalizedError;
    }

    /**
     * 获取错误类型
     */
    getErrorType(error) {
        if (error instanceof TypeError) {
            if (error.message.includes('Network')) return 'NETWORK_ERROR';
            if (error.message.includes('JSON')) return 'PARSE_ERROR';
        }

        if (error instanceof ReferenceError) {
            return 'REFERENCE_ERROR';
        }

        if (error instanceof SyntaxError) {
            return 'SYNTAX_ERROR';
        }

        if (error.code === 'ECONNABORTED') {
            return 'TIMEOUT_ERROR';
        }

        return 'UNKNOWN_ERROR';
    }

    /**
     * 获取错误级别
     */
    getErrorLevel(error) {
        if (error.level) return error.level;

        if (error instanceof SyntaxError || error instanceof ReferenceError) {
            return 'critical';
        }

        if (error.code === 'ECONNABORTED') {
            return 'warn';
        }

        return 'error';
    }

    /**
     * 生成错误ID
     */
    generateErrorId() {
        return `error_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
    }

    /**
     * 日志记录
     */
    async logError(error) {
        const logMethod = this.getLogMethod(error.level);

        const logData = {
            id: error.id,
            type: error.type,
            level: error.level,
            message: error.message,
            timestamp: error.timestamp,
            stack: error.stack,
            code: error.code,
            status: error.status,
            url: error.url,
            userAgent: error.userAgent,
            details: error.details
        };

        try {
            logMethod.call(this.logger, `[${error.level.toUpperCase()}] ${error.message}`, logData);
        } catch (logError) {
            console.error('Error logging failed:', logError);
        }
    }

    /**
     * 获取日志方法
     */
    getLogMethod(level) {
        switch (level) {
            case 'debug': return this.logger.debug || this.logger.log;
            case 'info': return this.logger.info || this.logger.log;
            case 'warn': return this.logger.warn || this.logger.log;
            case 'error': return this.logger.error || this.logger.log;
            case 'critical': return this.logger.error || this.logger.log;
            default: return this.logger.log;
        }
    }

    /**
     * 通知用户
     */
    async notifyUser(error) {
        const message = error.userMessage || this.getUserMessage(error);
        const duration = this.getNotificationDuration(error.level);

        const notification = {
            id: error.id,
            type: this.getNotificationType(error.level),
            title: this.errorTypes[error.type] || '错误',
            message,
            duration,
            actions: this.getNotificationActions(error)
        };

        try {
            if (this.notificationManager) {
                await this.notificationManager.show(notification);
            } else {
                this.showBrowserNotification(notification);
            }
        } catch (notificationError) {
            console.error('Error notification failed:', notificationError);
        }
    }

    /**
     * 获取用户消息
     */
    getUserMessage(error) {
        const messages = {
            'NETWORK_ERROR': '网络连接错误，请检查您的网络设置',
            'AUTH_ERROR': '认证失败，请重新登录',
            'PERMISSION_ERROR': '权限不足，无法执行此操作',
            'VALIDATION_ERROR': '数据验证失败，请检查输入内容',
            'SERVER_ERROR': '服务器错误，请稍后重试',
            'TIMEOUT_ERROR': '请求超时，请检查网络连接',
            'PARSE_ERROR': '数据解析错误，请刷新页面重试',
            'UNKNOWN_ERROR': '发生未知错误，请重试'
        };

        return messages[error.type] || '操作失败，请重试';
    }

    /**
     * 获取通知类型
     */
    getNotificationType(level) {
        const types = {
            'debug': 'info',
            'info': 'info',
            'warn': 'warning',
            'error': 'error',
            'critical': 'error'
        };

        return types[level] || 'error';
    }

    /**
     * 获取通知持续时间
     */
    getNotificationDuration(level) {
        const durations = {
            'debug': 3000,
            'info': 5000,
            'warn': 7000,
            'error': 10000,
            'critical': 15000
        };

        return durations[level] || 5000;
    }

    /**
     * 获取通知操作
     */
    getNotificationActions(error) {
        const actions = [
            { text: '关闭', action: 'dismiss' }
        ];

        // 添加重试按钮
        if (error.type === 'NETWORK_ERROR' || error.type === 'TIMEOUT_ERROR') {
            actions.unshift({ text: '重试', action: 'retry' });
        }

        // 添加刷新按钮
        if (error.type === 'SERVER_ERROR' || error.type === 'PARSE_ERROR') {
            actions.unshift({ text: '刷新', action: 'refresh' });
        }

        return actions;
    }

    /**
     * 显示浏览器通知
     */
    showBrowserNotification(notification) {
        // 简单的浏览器通知实现
        if (typeof document !== 'undefined') {
            const notificationEl = document.createElement('div');
            notificationEl.className = `notification notification-${notification.type}`;
            notificationEl.innerHTML = `
                <div class="notification-content">
                    <div class="notification-title">${notification.title}</div>
                    <div class="notification-message">${notification.message}</div>
                    <div class="notification-actions">
                        ${notification.actions.map(action =>
                            `<button class="notification-action" data-action="${action.action}">${action.text}</button>`
                        ).join('')}
                    </div>
                </div>
            `;

            // 添加到页面
            document.body.appendChild(notificationEl);

            // 自动移除
            setTimeout(() => {
                if (notificationEl.parentNode) {
                    notificationEl.parentNode.removeChild(notificationEl);
                }
            }, notification.duration);
        }
    }

    /**
     * 错误上报
     */
    async reportError(error) {
        if (!this.errorReporting) return;

        const reportData = {
            errorId: error.id,
            type: error.type,
            level: error.level,
            message: error.message,
            stack: error.stack,
            timestamp: error.timestamp,
            url: error.url,
            userAgent: error.userAgent,
            details: error.details
        };

        try {
            await this.errorReporting.report(reportData);
        } catch (reportError) {
            console.error('Error reporting failed:', reportError);
        }
    }

    /**
     * 处理通知回调
     */
    async handleNotification(notificationId, action) {
        if (action === 'retry') {
            // 触发重试事件
            window.dispatchEvent(new CustomEvent('error-retry', {
                detail: { notificationId }
            }));
        } else if (action === 'refresh') {
            // 刷新页面
            window.location.reload();
        }
    }

    /**
     * 创建特定类型的错误处理器
     */
    createHandler(type, config = {}) {
        return (error, options = {}) => {
            return this.handle(error, { ...config, type, ...options });
        };
    }

    /**
     * handleError方法 - handle方法的别名，提供更直观的接口
     */
    async handleError(error, options = {}) {
        return this.handle(error, options);
    }

    /**
     * 包装函数以添加错误处理
     */
    wrap(fn, options = {}) {
        return async (...args) => {
            try {
                return await fn(...args);
            } catch (error) {
                await this.handle(error, options);
                throw error;
            }
        };
    }

    /**
     * 包装Promise以添加错误处理
     */
    wrapPromise(promise, options = {}) {
        return promise.catch(error => {
            this.handle(error, options);
            throw error;
        });
    }

    /**
     * 获取错误统计
     */
    getStats() {
        // 这里可以实现错误统计逻辑
        return {
            total: 0,
            byType: {},
            byLevel: {}
        };
    }

    /**
     * 清理资源
     */
    cleanup() {
        // 移除全局错误监听器
        if (typeof window !== 'undefined') {
            window.removeEventListener('error', this.handleGlobalError);
            window.removeEventListener('unhandledrejection', this.handleUnhandledRejection);
        }
    }
}

// 导出ErrorHandler
window.ErrorHandler = ErrorHandler;